﻿#include "audio_device.h"
#include "listener.h"

using namespace xcast;

template<>
std::set<Device::Audio::Listener::Interface*>
        Base::Listener::Interface<Device::Audio::Listener::Interface>::listener_ =
        std::set<Device::Audio::Listener::Interface*>();

class AudioDeviceListener : public Base::Listener::Interface<Device::Audio::Listener::Interface> {
public:
  static void OnAddMic(const char* device_id, bool add) {
    for (auto it : listener_) {
      it->OnAddMic(device_id, add);
    }
  }

  static void OnAddSpeaker(const char* device_id, bool add) {
    for (auto it : listener_) {
      it->OnAddSpeaker(device_id, add);
    }
  }
};

namespace Device {
namespace Audio {
namespace Listener {
void Add(Interface* listener) {
  AudioDeviceListener::Add(listener);
}

void Remove(Interface* listener) {
  AudioDeviceListener::Remove(listener);
}
}

namespace XcastEvent {
void OnAddMic(const char* device_id, bool add) {
  AudioDeviceListener::OnAddMic(device_id, add);
}

void OnAddSpeaker(const char* device_id, bool add) {
  AudioDeviceListener::OnAddSpeaker(device_id, add);
}
}

bool IsSelectedMic(const char* device_id) {
  xcast_data mic_name = xcast_core::get_property(XC_MIC_DEFAULT);
  size_t size = mic_name.size();
  if (size == 0) {
    return false;
  }
  return 0 == strcmp(mic_name, device_id);
}

int SelectMic(const char* device_id) {
  xcast_data mic_name(device_id);
  int ret = xcast_core::set_property(XC_MIC_DEFAULT, mic_name);
  xcast_data state = xcast_core::get_property(XC_STREAM_STATE, "wemeet-channel", "audio-out");
  if (xc_stream_running == state.int32_val()) {
    xcast_core::set_property(XC_STREAM_CAPTURE, "wemeet-channel", "audio-out", mic_name);
  }
  return ret;
}

uint32_t GetMicVolume(const char* device_id) {
  xcast_data mic_name = xcast_core::get_property(XC_MIC_DEFAULT);
  xcast_data data;
  if (device_id && strlen(device_id)) {
    data = xcast_core::get_property(XC_MIC_VOLUME, device_id);
  } else {
    data = xcast_core::get_property(XC_MIC_VOLUME, mic_name.str_val());
  }

  return data.uint32_val();
}

void SetMicVolume(const char* device_id, uint32_t volume) {
  xcast_data mic_name = xcast_core::get_property(XC_MIC_DEFAULT);
  xcast_data data(volume);
  int ret;
  if (device_id && strlen(device_id)) {
    ret = xcast_core::set_property(XC_MIC_VOLUME, device_id, data);
  } else {
    ret = xcast_core::set_property(XC_MIC_VOLUME, mic_name.str_val(), data);
  }
}

bool IsSelectedSpeaker(const char* device_id) {
  xcast_data speaker_name = xcast_core::get_property(XC_SPEAKER_DEFAULT);
  size_t size = speaker_name.size();
  if (size == 0) {
    return false;
  }
  return 0 == strcmp(speaker_name, device_id);
}

int SelectSpeaker(const char* device_id) {
  xcast_data speaker_name(device_id);
  int ret = xcast_core::set_property(XC_SPEAKER_DEFAULT, speaker_name);
  return ret;
}

int PreviewMic(const char* device_id, bool on) {
  xcast_data mic_name = xcast_core::get_property(XC_MIC_DEFAULT);
  xcast_data data(on);
  int ret;
  if (device_id && strlen(device_id)) {
    ret = xcast_core::set_property(XC_MIC_PREVIEW, device_id, data);
  } else {
    ret = xcast_core::set_property(XC_MIC_PREVIEW, mic_name.str_val(), data);
  }
  
  return ret;
}

int PreviewSpeaker(const char* device_id, bool on, const char* file_path, bool loop_back, int loop_count) {
  xcast_data speaker_name = xcast_core::get_property(XC_SPEAKER_DEFAULT);
  xcast_data data(on);
  int ret;
  if (device_id && strlen(device_id)) {
    ret = xcast_core::set_property(XC_SPEAKER_PREVIEW, device_id, data);
    if (ret != XCAST_OK)
      return ret;
    ret = SetAccompanyMusic(on, file_path, loop_back, loop_count);
  } else {
    ret = xcast_core::set_property(XC_SPEAKER_PREVIEW, speaker_name.str_val(), data);
    if (ret != XCAST_OK) {
      return ret;
    }
    ret = SetAccompanyMusic(on, file_path, loop_back, loop_count);
  }
  return ret;
}

int SetAccompanyMusic(bool on, const char* file_path, bool loop_back, int loop_count) {
  xcast_data params;

  if (on) {
    params["enabled"] = true;
    params["path"] = file_path;
    params["loopback"] = loop_back;
    params["loopcount"] = loop_count;     
  }
  else {
    params["enabled"] = false;
  }
  return xcast_core::set_property(XC_ACCOMPANY_ENABLED, params);
}

int SetSpeakerMode(bool earphone_enable) {
  xcast_data default_speaker = xcast_core::get_property(XC_SPEAKER_DEFAULT);
  xcast_data enable(earphone_enable);
  int ret = xcast_core::set_property(XC_SPEAKER_EARPHONE_MODE, default_speaker.str_val(), enable);
  return ret;
}

uint32_t GetSpeakerVolume(const char* device_id) {
  xcast_data speaker_name = xcast_core::get_property(XC_SPEAKER_DEFAULT);
  xcast_data data;
  if (device_id && strlen(device_id)) {
    data = xcast_core::get_property(XC_SPEAKER_VOLUME, device_id);
  } else {
    data = xcast_core::get_property(XC_SPEAKER_VOLUME, speaker_name.str_val());
  }

  return data.uint32_val();
}

void SetSpeakerVolume(const char* device_id, uint32_t volume) {
  xcast_data speaker_name = xcast_core::get_property(XC_SPEAKER_DEFAULT);
  xcast_data data(volume);
  int ret;
  if (device_id && strlen(device_id)) {
    ret = xcast_core::set_property(XC_SPEAKER_VOLUME, device_id, data);
  } else {
    ret = xcast_core::set_property(XC_SPEAKER_VOLUME, speaker_name.str_val(), data);
  }
}
}
}
